// dep: MouseUtil.js Util.js
var DragAndDrop = {

	currentDragTarget : '',

	whatIsDragging : function() {
		return DragAndDrop.currentDragTarget;
	},

	isDragging: function() {
		return '' != DragAndDrop.whatIsDragging();
	},

	startDrag: function( event, target ) {
		document.onmouseup = DragAndDrop.stopDrag;
		if ( DragAndDrop.isDragging() ) {
			DragAndDrop.stopDrag();
		} else {
			DragAndDrop.currentDragTarget = MouseUtil.getMouseXY( event );
			DragAndDrop.currentDragTarget.target = target;
			var off = Util.elementPosition( target );
			off.x = DragAndDrop.currentDragTarget.x - off.x;
			off.y = DragAndDrop.currentDragTarget.x - off.y;
			DragAndDrop.currentDragTarget.off = off;
			document.onmousemove = DragAndDrop.dragging;

			var handle_id = Util.attribute( target, 'handle_id' );
			//DragAndDrop.currentDragTarget.big_handle = Util.id( 'big_handle.' + handle_id );
		}
	},


	dragging: function( event ) {
		var tmp = MouseUtil.getMouseXY( event )
		var start = DragAndDrop.whatIsDragging();
		var target = start.target;

		var size = Util.elementSize( target );
		//DragAndDrop.currentDragTarget.big_handle.style.left = ( size.w - 24 ) + 'px';

		Util.moveElement( target
			, tmp.x - 5 - DragAndDrop.currentDragTarget.off.x
			, tmp.y - 5
		);
	},

	stopDrag: function() {
		document.onmousemove = '';
		DragAndDrop.currentDragTarget = '';
	},

	dndCollapsed : function( container ) {
		return (
			Util.attribute( container, TimedUtil.collapsed )
			|| Util.attribute( container, TimedUtil.collapsing )
		);
	},

	dndHideNode: function( node ) {
		if ( DragAndDrop.dndCollapsed( node.parentNode ) ) {
			DragAndDrop.dndOnStyle( node );
		} else { 
			DragAndDrop.dndOffStyle( node );
			node.parentNode.onclick = '';
		}
	},

	dndOffStyle: function( node ) {
		var container = node.parentNode;

		node.style.background = container.style.background;
		node.style.border = '';

		var handle_id = Util.attribute( container, 'handle_id' );
		Util.visible( Util.id( 'drag_handle.'     + handle_id ) );
		Util.invisible( Util.id( 'collapse_handle.' + handle_id ) );
		Util.invisible( Util.id( 'kill_handle.'     + handle_id ) );
		//Util.invisible( Util.id( 'big_handle.'      + handle_id ) );
	},

	dndOnStyle: function( node ) {
		var container = node.parentNode;

		node.style.background = 'rgb(255,255,100)';
		node.style.border = '2px solid black';

		var handle_id = Util.attribute( container, 'handle_id' );
		Util.visible( Util.id( 'drag_handle.'     + handle_id ) );
		Util.visible( Util.id( 'collapse_handle.' + handle_id ) );
		Util.visible( Util.id( 'kill_handle.'     + handle_id ) );
		//Util.visible( Util.id( 'big_handle.'      + handle_id ) );
	},

	dndShowNode: function( node ) {
		if ( !DragAndDrop.isDragging() ) {
			DragAndDrop.dndOnStyle( node );
			node.onmousedown = function( event ) {
				DragAndDrop.startDrag( event, node.parentNode );
			};
			node.onmouseup = function() {
				DragAndDrop.stopDrag();
			};
		}
	},

	initDragHandle: function( node ) {
		var container = node.parentNode;

		var size = Util.elementSize( container );
		var pos = Util.elementPosition( container );

		var handle_id = Util.nextId();
		Util.attribute( container, 'handle_id',              handle_id );

		container.onmouseout = function() { DragAndDrop.dndHideNode( node ); };
		container.onmouseover = function() { DragAndDrop.dndShowNode( node ); };

		var collapse = Util.newNode( 'span', {className:'collapse_handle _handle'} );
		collapse.onclick = function() { DragAndDrop.collapse( node ); }
		collapse.appendChild( Util.newTxt( '[||]' ) );
		node.appendChild( collapse );

		var kill = Util.newNode( 'span', {className:'kill_handle _handle'} );
		kill.onclick = function() { Util.kill( node ); }
		kill.appendChild( Util.newTxt( '[X]' ) );
		node.appendChild( kill );

		// var big = Util.newNode( 'span', {className:'big_handle _handle'} );
		// big.onclick = function() { Util.big( node ); }
		// big.appendChild( Util.newTxt( '↵' ) );
		// big.style.position = 'relative';
		// big.style.left = ( size.w - 24 ) + 'px';
		// container.appendChild( big );

		Util.attribute( node,     'id', 'drag_handle.' +     handle_id );
		Util.attribute( collapse, 'id', 'collapse_handle.' + handle_id );
		Util.attribute( kill,     'id', 'kill_handle.' +     handle_id );
		//Util.attribute( big,      'id', 'big_handle.' +      handle_id );
	},

	collapse : function( node ) {
		var container = node.parentNode;
		if ( !container.getAttribute( TimedUtil.fading ) ) {
			container.setAttribute( TimedUtil.fading, true );
			if ( container.getAttribute( TimedUtil.collapsed ) ) {
				DragAndDrop.collapseIn( node );
			} else {
				DragAndDrop.collapseOut( node );
			}
		}
	},

	collapseIn : function( node ) {
		 var container = node.parentNode;
		 var doneFading = function( xo ) {
			 container.setAttribute( TimedUtil.fading, '' );
			 container.setAttribute( TimedUtil.collapsed, '' );
		 };
		 Util.kids( 
			 container
			 , function( n ) { return n != node; }
			 , function( n ) { TimedUtil.fadeInElement( n, doneFading ); }
		 );
	},

	collapseOut : function( node ) {
		var container = node.parentNode;
		DragAndDrop.dndOnStyle( node );
		var doneFading = function( xo ) {
			container.setAttribute( TimedUtil.fading, '' );
			container.setAttribute( TimedUtil.collapsed, true );
			DragAndDrop.dndOnStyle( node );
		};
		Util.kids( 
			container
			, function( n ) { return n != node; }
			, function( n ) { TimedUtil.fadeOutElement( n, doneFading ); }
		);
	},

	testIsDragHandle: function( node ) {
		return Util.hasClass( node, 'drag_handle' );
	},

	initDnd: function() {
		Util.walkDom(
			DragAndDrop.testIsDragHandle
			, DragAndDrop.initDragHandle 
		);
	},

	noop: function(){}
};
